package cn.est.controller;
import cn.est.constants.ResultEnum;
import cn.est.dto.BaseException;
import cn.est.pojo.SmsLog;
import cn.est.constants.Constants;
import cn.est.dto.Page;
import cn.est.dto.Result;
import cn.est.service.SmsLogService;
import cn.est.utils.EmptyUtils;
import cn.est.utils.ResultUtils;
import javax.annotation.Resource;

import cn.est.utils.redis.RedisKeyUtils;
import cn.est.utils.redis.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;

@Controller
@RequestMapping("/client/smsLog")
public class SmsLogController {

    private Logger log= LoggerFactory.getLogger(SmsLogController.class);

    @Resource
    private SmsLogService smsLogService;

    @Autowired
    private RedisUtils redisUtils;

    @PostMapping(value = "verifyCode")
    @ResponseBody
    public Result verifyCode(String phone,Integer codeType) throws BaseException {
        log.info("发送短信phone：{},短信类型codeType:{}", phone, codeType);
        Result result = null;
        // 1.判断手机号是否正确
        if(!checkPhone(phone)){
            log.info("手机号码错误phone:{}", phone);
            return ResultUtils.returnFail("手机号码错误", ResultEnum.FAIL_PARAM.getCode());
        }
        // 2.判断短信类型是否正确
        if(!checkCodeType(codeType)){
            log.info("短信类型错误codeType:{}", codeType);
            return ResultUtils.returnFail("短信类型错误", ResultEnum.FAIL_PARAM.getCode());
        }
        // 3.验证码发送频率
        if(!checkSmsCode(phone, codeType)){
            log.info("验证码发送频率过高");
            return ResultUtils.returnFail("请勿重复发送。");
        }
        smsLogService.sendMessage(phone, codeType, null);
        result = ResultUtils.returnSuccess();
        return result;
    }

    /**
     * 验证验证码
     * @param phone
     * @param codeType
     */
    private boolean checkSmsCode(String phone, Integer codeType) {
        boolean flag = false;
        String key = RedisKeyUtils.formatKeyWithPrefix(Constants.Redis.PREFIX_SMS, codeType.toString(), phone);
        String smsCode = redisUtils.getValue(key);
        // 判断验证码是否有效期内发送，如果不存在说明已经过了有效期，可以发送
        if(StringUtils.isBlank(smsCode)){
            flag = true;
        }
        return flag;
    }


    /**
     * 验证手机号
     * @param phone
     */
    private boolean checkPhone(String phone) throws BaseException {
        boolean flag = false;
        if(!StringUtils.isBlank(phone)){
            flag = phone.matches(Constants.PHONE_REGSTR);
        }
        return flag;
    }

    /**
     * 验证短信类型
     * @param codeType
     */
    private boolean checkCodeType(Integer codeType) {
        boolean flag = false;
        if(codeType != null){
            // 如果是不已定义的短信类型，不允许发送
            if(codeType.equals(Constants.Sms.TYPE_REGIST_OR_LOGIN) || codeType.equals(Constants.Sms.TYPE_UP_PASS)
                    || codeType.equals(Constants.Sms.TYPE_NOTICE) || codeType.equals(Constants.Sms.TYPE_SUBMIT_CHECK)){
                flag = true;
            }
        }
        return flag;
    }


    @RequestMapping("/search")
    @ResponseBody
    public Page<SmsLog> searchSmsLog(@RequestParam Map<String,Object> param) {
        Page<SmsLog> smsLogPage = null;
        try {
            Integer pageNo= EmptyUtils.isEmpty(param.get("pageNo"))? Page.DEFAULT_PAGE_NO:Integer.parseInt((String) param.get("pageNo"));
            Integer pageSize= EmptyUtils.isEmpty(param.get("pageSize"))? Page.DEFAULT_PAGE_SIZE:Integer.parseInt((String) param.get("pageSize"));
            smsLogPage  = smsLogService.querySmsLogPageByMap(param, pageNo, pageSize);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return smsLogPage;
    }

    @RequestMapping("/saveOrUpdateSmsLog")
    @ResponseBody
    public Result saveOrUpdateSmsLog(SmsLog smsLog){
        Integer flag=0;
        try {
            if(EmptyUtils.isEmpty(smsLog.getId())){
                flag=smsLogService.qdtxAddSmsLog(smsLog);
            }else{
                flag=smsLogService.qdtxModifySmsLog(smsLog);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag>=1?ResultUtils.returnSuccess():ResultUtils.returnFail();
    }

    @RequestMapping("/getSmsLogById")
    @ResponseBody
    public Result getSmsLogById(Long id){
        Result result= ResultUtils.returnSuccess();
        SmsLog smsLog=null;
        try {
            smsLog=smsLogService.getSmsLogById(id);
            result.setData(smsLog);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @RequestMapping("/batchRemoveSmsLog")
    @ResponseBody
    public Result batchRemoveSmsLog(String ids){
        Integer flag=0;
        try {
            flag=smsLogService.qdtxBatchDeleteSmsLog(ids);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtils.returnSuccess();
    }

    @RequestMapping("/removeSmsLogById")
    @ResponseBody
    public Result removeSmsLogById(Long id){
        Integer flag=0;
        try {
            flag=smsLogService.qdtxDeleteSmsLogById(id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtils.returnSuccess();
    }
}
